package com.xy.demo.Util;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xy.demo.feishu.model.*;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

public class Util {

    public static Long second() {
        return Long.valueOf(System.currentTimeMillis() / 1000);
    }

    public static long convertTime(long time) {
        String s = String.valueOf(time);
        if (s.length() == 10) {
            return time * 1000L;
        }
        return time;
    }

    public static String toString(Object o, String sp) {
        if (o == null)
            return "";
        if (o instanceof List) {
            List list = (List) o;
            if (list.size() == 0) return "";
            Object obj = null;
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < list.size(); i++) {
                obj = list.get(i);
                if (sb.length() > 0) {
                    sb.append(sp);
                }
                sb.append(String.valueOf(obj));
            }
            return sb.toString();
        } else if (o instanceof JsonNode) {
            JsonNode json = (JsonNode) o;
            return json.toString();
        }
        return String.valueOf(o);
    }


    public static String toString(Object o) {
        return toString(o, ",");
    }


    public static Long toLong(Object o) {
        if (o == null || "".equals(Util.toString(o)) || "null".equals(Util.toString(o)))
            return null;
        return Long.valueOf(String.valueOf(o));
    }

    public static String formatDate(long time, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        return df.format(convertTime(time));
    }


    /**
     * str -> Date
     * @param str
     * @return
     */
    public static Date StringToDate(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date time = null;
        try {
            time = sdf.parse(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return time;
    }

    /**
     *  当前日期 0点
     * @return
     */
    public static Long  startTimeForDay() {
        Calendar calendarDay =Calendar.getInstance();
        String time = DateFormatUtils.format(calendarDay,"yyyy-MM-dd");
        String startTimeForDay = time + " 00:00:00";
        Date date = StringToDate(startTimeForDay);
        return date.getTime()/1000;
    }

    /**
     * 当前日期所在周 o点
     * @return
     */
    public static Long  startTimeForWeek() {
        Calendar calendarWeek =Calendar.getInstance();
        calendarWeek.setTime(new Date());
        calendarWeek.add(Calendar.DATE, 0 * 7);    // 0 表示当前周，-1 表示上周，1 表示下周，以此类推
        calendarWeek.setFirstDayOfWeek(Calendar.MONDAY);  //以周一为首日
        calendarWeek.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        String time = DateFormatUtils.format(calendarWeek,"yyyy-MM-dd");
        String startTimeForDay = time + " 00:00:00";
        Date date = StringToDate(startTimeForDay);
        return date.getTime()/1000;
    }

    /**
     * 当前日期所在月 o点
     * @return
     */
    public static Long  startTimeForMonth() {
        Calendar calendarMonth =Calendar.getInstance();
        calendarMonth.setTime(new Date());
        calendarMonth.add(Calendar.MONTH,0);  //可省略
        calendarMonth.set(Calendar.DAY_OF_MONTH, calendarMonth.getActualMinimum(Calendar.DAY_OF_MONTH));
        String time = DateFormatUtils.format(calendarMonth,"yyyy-MM-dd");
        String startTimeForDay = time + " 00:00:00";
        Date date = StringToDate(startTimeForDay);
        return date.getTime()/1000;
    }

    /**
     * 当前日期所在周 o点
     * @return
     */
    public static Long  startTimeForMonth(Long dateTime) {
        Calendar calendarMonth =Calendar.getInstance();
        calendarMonth.setTime(new Date(Util.convertTime(dateTime)));
        calendarMonth.add(Calendar.MONTH,0);  //可省略
        calendarMonth.set(Calendar.DAY_OF_MONTH, calendarMonth.getActualMinimum(Calendar.DAY_OF_MONTH));
        String time = DateFormatUtils.format(calendarMonth,"yyyy-MM-dd");
        String startTimeForDay = time + " 00:00:00";
        Date date = StringToDate(startTimeForDay);
        return date.getTime()/1000;
    }

    /**
     * 当前日期所在年 o点
     * @return
     */
    public static Long  startTimeForYear() {
        Calendar calendarMonth =Calendar.getInstance();
        calendarMonth.setTime(new Date());
        calendarMonth.add(Calendar.YEAR,0);  //可省略
        calendarMonth.set(Calendar.DAY_OF_YEAR, calendarMonth.getActualMinimum(Calendar.DAY_OF_YEAR));
        String time = DateFormatUtils.format(calendarMonth,"yyyy-MM-dd");
        String startTimeForDay = time + " 00:00:00";
        Date date = StringToDate(startTimeForDay);
        return date.getTime()/1000;
    }


    public static boolean isEmpty(Object o) {
        if (o == null) {
            return true;
        }
        if (o instanceof Long) {
            if (Util.equals(o, Long.valueOf(0))) {
                return true;
            }
        } else if (o instanceof BigDecimal) {
            if (Util.equals(o, BigDecimal.ZERO)) {
                return true;
            }
        } else if (o instanceof String) {
            if ("".equals(o) || "undefined".equals(o) || "null".equals(o) || "NULL".equals(o)) {
                return true;
            }
        } else if (o instanceof List) {
            List l = (List) o;
            return l.isEmpty();
        }
        return true;
    }


    /**
     * 转换为百分数
     * @param a
     * @return
     */
    public static String covertPercent(BigDecimal a){
        NumberFormat percent = NumberFormat.getPercentInstance();
        percent.setMaximumFractionDigits(2);
        return percent.format(a.doubleValue());
    }


    public static boolean equals(Object a, Object b) {
        if (a == null || b == null) {
            return false;
        } else if (a instanceof String && b instanceof String) {
            return String.valueOf(a).equals(String.valueOf(b));
        } else if ((a instanceof Long && b instanceof Long)) {
            return Long.parseLong(String.valueOf(a)) == Long.parseLong(String.valueOf(b));
        } else if (a instanceof Integer && b instanceof Integer) {
            return Integer.parseInt(String.valueOf(a)) == Integer.parseInt(String.valueOf(b));
        } else if (a instanceof BigDecimal && b instanceof BigDecimal) {
            return ((BigDecimal) a).compareTo((BigDecimal) b) == 0;
        }
        return a.equals(b);
    }

    public static int toInt(Object o) {
        if (Util.isEmpty(o))
            return 0;
        if (o instanceof BigDecimal)
            return ((BigDecimal) o).intValue();
        return Integer.parseInt(String.valueOf(o));
    }

    public static JsonNode toJson(Object data) {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = null;
        try{
            jsonNode  = mapper.readTree(data.toString());
        }catch (Exception e ){
            e.printStackTrace();
        }

        return jsonNode;
    }

    public static void  feishu(String url,StringBuilder str,String title){
        Long time = Util.second();
        String ruleName="";
        ruleName = Util.formatDate(Util.second(),"yyyy-MM-dd") + title;
            Param param = new Param();
            param.setTimestamp(time);
            param.setMsg_type("interactive");
            Card card = new Card();
            card.setHeader(new FSHeader(new Title(ruleName)));
            ArrayList<Element> objects = new ArrayList<>();
            Element element = new Element();
            element.setTag("div");
            element.setText(new Text(str.toString()));
            objects.add(element);
            card.setElements(objects);
            param.setCard(card);
            JsonNode jsonNode = Util.toJson(param);
            SendSignHttpsClient.doPostForJson(url,  JSON.toJSONString(param));

    }


    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        if (a == null) return b;
        if (b == null) return a;
        return a.add(b);
    }

    public static BigDecimal add(BigDecimal a, BigDecimal b, BigDecimal c) {
        return Util.add(Util.add(a, b), c);
    }

    public static BigDecimal subtract(BigDecimal a, BigDecimal b) {
        if (b == null) return a;
        if (a == null) return BigDecimal.ZERO.subtract(b);
        return a.subtract(b);
    }

    public static Integer add(Integer a, Integer b) {
        if (a == null) return b;
        if (b == null) return a;
        return Integer.valueOf(a.intValue() + b.intValue());
    }

    public static Integer subtract(Integer a, Integer b) {
        if (a == null && b == null) return Integer.valueOf(0);
        if (a == null) return 0 - b;
        if (b == null) return a;
        return a - b;
    }

    public static Long add(Long a, Long b) {
        if (a == null) return b;
        if (b == null) return a;
        return Long.valueOf(a.longValue() + b.longValue());
    }

    public static Long add(Long a, int b) {
        return add(a, Util.toLong(b));
    }

    public static Long subtract(Long a, Long b) {
        if (a == null && b == null) return Long.valueOf(0);
        if (a == null) return 0 - b;
        if (b == null) return a;
        return a - b;
    }

    public static Long subtract(Long a, int b) {
        return subtract(a, Util.toLong(b));
    }

    public static BigDecimal multiply(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) return null;
        return a.multiply(b);
    }

    public static BigDecimal multiply(BigDecimal a, Long b) {
        return multiply(a, Util.toBigDecimal(b));
    }

    public static Long multiply(Long a, Long b) {
        if (a == null || b == null) return null;
        return a * b;
    }

    public static BigDecimal divide(BigDecimal a, BigDecimal b) {
        //return divide(a, b, BigDecimal.ROUND_UP);

        return divide(a, b, 2, BigDecimal.ROUND_UP);
    }

    public static String divide(int doCount,int count,int num){
        // 创建一个数值格式化对象
        if(count == 0){
            return "0%";
        }
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后num位
        numberFormat.setMaximumFractionDigits(num);
        numberFormat.setRoundingMode(RoundingMode.DOWN);
        String result = numberFormat.format((float) doCount / (float) count);
        return result ;
    }


    public static BigDecimal divide(BigDecimal a, BigDecimal b, int roundMode) {
        return divide(a, b, 2, BigDecimal.ROUND_UP);
    }

    public static BigDecimal divide(BigDecimal a, BigDecimal b, int scale, int roundMode) {
        if (a == null || b == null) return null;
        if (Util.equals(a, BigDecimal.ZERO)) {
            return BigDecimal.ZERO;
        }
        return a.divide(b, scale, roundMode);
    }

    public static BigDecimal percent(BigDecimal a) {
    	/*
        if (a == null) return null;
        return a.divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_UP);
        */
        return divide(a, Util.toBigDecimal(100), 2, BigDecimal.ROUND_UP);
    }

    public static BigDecimal percent(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) return null;
        return Util.divide(Util.multiply(a, BigDecimal.valueOf(100)), b, 2, BigDecimal.ROUND_UP);
    }

    public static BigDecimal multiplyPercent(BigDecimal a, BigDecimal percent) {
        return Util.percent(Util.multiply(a, percent));
    }


    public static BigDecimal toBigDecimal(Object o) {
        if (Util.isEmpty(o))
            return BigDecimal.valueOf(0);
        return new BigDecimal(Util.toString(o));
    }

    public static BigDecimal toMoney(Object o) {
        if (Util.isEmpty(o))
            return BigDecimal.valueOf(0);
        if (o instanceof BigDecimal) {
            return ((BigDecimal) o).setScale(2, BigDecimal.ROUND_UP);
        }
        return BigDecimal.valueOf(Double.parseDouble(String.valueOf(o))).setScale(2, BigDecimal.ROUND_UP);
    }

    public static boolean more(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return false;
        }
        return a.compareTo(b) > 0;
    }

    public static boolean more(Long a, Long b) {
        return a.compareTo(b) > 0;
    }

    public static boolean moreThan(BigDecimal a, BigDecimal b) {
        return !Util.less(a, b);
    }

    public static boolean moreThan(Long a, Long b) {
        return !Util.less(a, b);
    }

    public static boolean less(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return true;
        }
        return a.compareTo(b) < 0;
    }

    public static boolean less(Long a, Long b) {
        return a.compareTo(b) < 0;
    }

    public static boolean lessThan(BigDecimal a, BigDecimal b) {
        return !Util.more(a, b);
    }

    public static boolean lessThan(Long a, Long b) {
        return !Util.more(a, b);
    }

    public static double ceilNumber(Object o){
        int bite = 0 ;
        if (equals(o,"")||equals(o,null)) {
            return 0;
        }
        Double number = Double.valueOf(toString(o));
        if(number<=0){
            return 0;
        }
        if(number<=10){
            return 10;
        }
        while (number>10){
            number = number/10;
            bite+=1;
        }
        return Math.ceil(number)*Math.pow(10,bite);
    }

    public static Long msStringTime(String datetime) {
        try {
            Calendar c = Calendar.getInstance();
            if (datetime.indexOf("/") != -1) {
                datetime = datetime.replaceAll("/", "-");
            }
            if(datetime.indexOf(" ")!=-1){
                datetime = datetime.substring(0,datetime.indexOf(" "));
            }

            if (datetime.indexOf("-") != -1) {
                if (datetime.length() == "yyyy-MM-dd".length() || datetime.length() == "yyyy-M-d".length() || datetime.length() == "yyyy-M-dd".length()||datetime.length() == "yyyy-MM-d".length()) {
                    c.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(datetime));
                } else if (datetime.length() == "yyyy-MM".length()) {
                    c.setTime(new SimpleDateFormat("yyyy-MM").parse(datetime));
                }
                return Long.valueOf(c.getTimeInMillis())/1000;
            }
        } catch (Exception e) {
           return null;
        }
        return ms()/1000;
    }
    /**
     * 当前日期所在周 o点
     *
     * @return
     */
    public static Long startTimeForMonth(Long dateTime, Integer addMonth) {
        Calendar calendarMonth = Calendar.getInstance();
        calendarMonth.setTime(new Date(Util.convertTime(dateTime)));
        calendarMonth.add(Calendar.MONTH, addMonth);  //可省略
        calendarMonth.set(Calendar.DAY_OF_MONTH, calendarMonth.getActualMinimum(Calendar.DAY_OF_MONTH));
        String time = DateFormatUtils.format(calendarMonth, "yyyy-MM-dd");
        String startTimeForDay = time + " 00:00:00";
        Date date = StringToDate(startTimeForDay);
        return date.getTime() / 1000;
    }

    /**
     * 取时间月末一天,若时间在当前月取当前时间
     * @param datetime
     * @return
     */
    public static Long msStringTime(Long datetime) {
        String data = formatDate(datetime,"yyyy-MM");
        String dataNow = formatDate(Util.second(),"yyyy-MM");
        if(!equals(data,dataNow)){
            return Util.subtract(startTimeForMonth(datetime,1),1);
        }
        return ms()/1000;
    }

    public static Long ms() {
        return Long.valueOf(System.currentTimeMillis());
    }



}
